﻿using OpenTK;
using OpenTK.Graphics.OpenGL;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace HokjesSluitenShowdown
{
    class Particles
    {
        public double fade;
        public double r, g, b, a;
        public double  x, y, z;
        public double  xi, yi, zi;
        public double xg, yg, zg;
    }
   
    public class ParticleGenerator 
    {
        private int MaxParticles = 500;
        private bool UsePoint = true;
        private bool Revive = true;
        private Single Life = 1;
        private Single Fade = 0f;
        private Vector3 Source = new Vector3(0, 0, 0);
        private Vector3 Direction = new Vector3(0, 100, 0);
        private Vector3 Gravity = new Vector3(0, -1, 0);        
        private Particles[] Particle;
        private Random rand = new Random();
        private System.Drawing.Color color;

        public ParticleGenerator() {}
        public ParticleGenerator(Vector3 Src, Vector3 _Direction, Vector3 Grvt, Single _Life = 1, int Max = 500, bool _UsePoint = false, Single _Fade = 0.1f, bool _Revive = false, System.Drawing.Color _color = new System.Drawing.Color())
        {
            Source = Src;
            Direction = _Direction;
            Gravity = Grvt;
            Life = _Life;
            MaxParticles = Max;
            UsePoint = _UsePoint;
            Fade = _Fade;
            Revive = _Revive;
            color = System.Drawing.Color.FromArgb(255, 255, 0, 0);
            Particle = new Particles[Max];
            InitParticles();
        }

        private void InitParticles()
        {
            for (int partID = 0; partID < MaxParticles; partID++)
            {
                Particle[partID] = new Particles();
                ReviveParticle(partID);
                Particle[partID].a = rand.NextDouble() - 0.5f;
            }
        }

        private void ReviveParticle(int partID)
        {
            if (partID < 0 || partID >= MaxParticles)
                return;

            Particles part = Particle[partID];
            part.fade = Fade;

            if (color.ToArgb() != 0)
            {
                part.r = color.R;
                part.g = color.G;
                part.b = color.B;
            }
            else
            {
                part.r = rand.NextDouble();
                part.g = rand.NextDouble();
                part.b = rand.NextDouble();
            }

            if (UsePoint)
                part.a = rand.NextDouble();                
            else
                part.a = 1f;

            part.x = Source.X;
            part.y = Source.Y;
            part.z = Source.Z;

            part.xi = Direction.X + (rand.NextDouble()) - 0.5f;
            part.yi = Direction.Y + (rand.NextDouble()) - 0.5f;
            part.zi = Direction.Z + (rand.NextDouble()) - 0.5f;

            part.xg = Gravity.X;
            part.yg = Gravity.Y;
            part.zg = Gravity.Z;
        }

        public void DrawParticles() {           
            GL.Disable(EnableCap.Lighting);
            GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);
 
            for (int partID = 0; partID < MaxParticles; partID++) {

                if (Particle[partID] != null)
                {
                    Double x = Particle[partID].x;
                    Double y = Particle[partID].y;
                    Double z = Particle[partID].z;

                    GL.PointSize(35);

                    GL.Color4(Particle[partID].r, Particle[partID].g, Particle[partID].b, Particle[partID].a); //Useless , because quads can't rotate (too hard for me)
                    GL.Begin(BeginMode.Polygon);
                        GL.Vertex3(x, y - 0.0075, z);
                        GL.Vertex3(x + 0.01, y, z);
                        GL.Vertex3(x + 0.005, y + 0.01, z);
                        GL.Vertex3(x - 0.005, y + 0.01, z);
                        GL.Vertex3(x - 0.01, y, z);
                    GL.End();

                    //Deplacement
                    Particle[partID].x += Particle[partID].xi / 50;
                    Particle[partID].y += Particle[partID].yi / 50;
                    Particle[partID].z += Particle[partID].zi / 50;

                    //Gravité
                    Particle[partID].xi -= Particle[partID].xg / 10;
                    Particle[partID].yi -= Particle[partID].yg / 10;
                    Particle[partID].zi -= Particle[partID].zg / 10;

                    Particle[partID].a -= Particle[partID].fade;
                    if (Particle[partID].a < 0)
                    {
                        if (Revive)
                            ReviveParticle(partID);
                        else
                            Particle[partID] = null;
                    }
                }
            }
            GL.Enable(EnableCap.Lighting);
            GL.Color4(1, 1, 1, 0.999);
        }
    }
}
